home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / The World of Computer Software.iso / mvssrc.zip / GPHPTSK < prev    next >
Text File  |  1992-04-13  |  19KB  |  497 lines

  1. #include "tcpincl"
  2. #include "tcph"
  3.  
  4. /*********************************************************************/
  5. /*                  prototypes                                       */
  6. /*********************************************************************/
  7. static void cleantoken(char *);
  8. static void cleanastring(char *);
  9. static int getftype(char *);
  10. static int menukeywd(char *,char *,char *);
  11. static int readaline(char *,FILE *,int);
  12. static void sendafile(char *,FILE *,int,int);
  13. static void sendamenu(char *,FILE *,int,int);
  14. static int process(char *,int);
  15. static void lookatsocket(int);
  16.  
  17. static struct menuitem
  18.     {
  19.     int  type;                 /* type of record to send  */
  20.     char desc[100];             /* user description string  */
  21.     char select[100];           /* select string to send    */
  22.     char hostname[100];         /* host name to connect to  */
  23.     int  port;                 /* host port to connect to  */
  24.     };
  25.  
  26. #include "ebdasc"
  27. /*=================================================================*/
  28. void  receive(int newsockfd,struct clientid clid)
  29. /**************************************************************/
  30. /*    this routine processes the data once a connection       */
  31. /*    has been accepted.  It just takes the data sent by the  */
  32. /*    client and prints it to sysprint, then sends it back    */
  33. /*    to the client.                                          */
  34. /*                                                            */
  35. /*             INPUT:   newsockfd  - socket descriptor        */
  36. /*                      clid       - takesocket structure...  */
  37. /**************************************************************/
  38. {
  39. char buffer[255];       /*buffer to hold clients character string */
  40. char outbuf[256];       /* buffer to hold an output character string */
  41. char *bufptr;           /* pointer into buffer strings above... */
  42. int sockfd;               /*socket descriptor for socket call...  */
  43. int retcode;              /*socket descriptor for socket call...  */
  44. int len;                  /*length of the buffer we're sent...    */
  45. int x;                    /*loop counter....                      */
  46. struct sockaddr_in clientaddress;  /* address of client           */
  47. int addrlen;              /* length of client address socket.     */
  48.  
  49. sockfd = takesocket(&clid,newsockfd);
  50. if(sockfd<0) tcperror("TAKESOCKET");
  51.  
  52. buffer[0] = 0;
  53. /***********************/
  54. /*  NOTE:  sometimes, if timing is right, RECV can return a 0 length */
  55. /* record when a connection is closed by the client!!  below is a   */
  56. /* hack to check for a 0 length record, and then terminate this     */
  57. /* connection if we got one.                                        */
  58. /***********************/
  59. while(1==1)
  60.     {
  61.     if((len=recv(sockfd,outbuf,sizeof(buffer)-1,0)) <= 0)
  62.         {
  63.         tcperror("RECV - ");
  64.         printf("tcp error! len=%d\n",len);
  65.         break;
  66.         }
  67.     *(outbuf+(len))=0;    /*make sure it's null terminated...*/
  68.     printf("len=%d;",len);
  69.     asctoebd(outbuf,len);
  70.     strcat(buffer,outbuf);
  71.     bufptr=buffer+(strlen(buffer)-2);
  72.     if(strcmp(bufptr,"\r\n")==0)
  73.         {
  74.         break;
  75.         }
  76.     }
  77. if(len<= 0) return;
  78. process(buffer,sockfd);
  79.  
  80. sprintf(outbuf,".\r\n");
  81. ebdtoasc(outbuf,strlen(outbuf));
  82. if(write(sockfd,outbuf,strlen(outbuf)) < 0) tcperror("SEND");
  83.  
  84. addrlen = sizeof(clientaddress);
  85. if(getpeername(sockfd,&clientaddress,&addrlen)!=0)
  86.     {
  87.     tcperror("GETPEERNAME");
  88.     printf("could not determine client address\n");
  89.     }
  90. printf("Connection from %s.\n",inet_ntoa(clientaddress.sin_addr));
  91. fflush(stdout);
  92. fflush(stderr);
  93.  
  94.  /*     lookatsocket(sockfd);    */
  95. if(close(sockfd)<0)
  96.     {
  97.     tcperror("CLOSE - ");
  98.     }
  99. }
  100. /*=================================================================*/
  101. /*=================================================================*/
  102. void cleantoken(char *token)
  103. /*******************************************************************/
  104. /*   This routine cleans up a token.  It converts all chars to     */
  105. /*   upper case and removes any leading spaces. Note that the      */
  106. /*   string is assumed to be null terminated.                      */
  107. /*                                                                 */
  108. /*       INPUT    token          pointer to token string.          */
  109. /*       OUTPUT   *token         string upcased, blanks removed.   */
  110. /*******************************************************************/
  111. {
  112. int x;                              /* loop counter */
  113. for(x=0;x<strlen(token);x++) *(token+x)=toupper(*(token+x));
  114. x=0;
  115. while(*(token+x)==' ') x++;
  116. if(x>0) memmove(token,(token+x),(strlen(token)-x)+1);
  117. };
  118. /*=================================================================*/
  119. void cleanastring(char *string)
  120. /****************************************************/
  121. /* This routine "cleans" a string by removing the   */
  122. /* leading spaces and trailing spaces+non-printable */
  123. /* characters.                                      */
  124. /****************************************************/
  125. {
  126. char *ptr;
  127. ptr = string;
  128.  
  129. /*  first clean up the beginning of the string... */
  130.  
  131. while (isspace(*ptr)!=0 && ptr <=(string+strlen(string)-1)) ptr++;
  132. strcpy(string,ptr);
  133.  
  134. /*    now look at the end of the string... */
  135.  
  136. ptr = string+strlen(string)-1;
  137. while (isgraph(*ptr)==0 && ptr >=string) ptr--;
  138. *(ptr+1)=0;
  139. }
  140. /*=================================================================*/
  141. /*=================================================================*/
  142. void cleanafileline(char *string)
  143. /****************************************************/
  144. /* This routine "cleans" an output line by removing */
  145. /* trailing spaces and non-printable characters.    */
  146. /****************************************************/
  147. {
  148. char *ptr;
  149. ptr = string;
  150.  
  151. /*  look at the end of the string... */
  152.  
  153. ptr = string+strlen(string)-1;
  154. while (isgraph(*ptr)==0 && ptr >=string) ptr--;
  155. *(ptr+1)=0;
  156. }
  157. /*=================================================================*/
  158. /*=================================================================*/
  159. int getftype(char *ident)
  160. /*******************************************************************/
  161. /*            This routine determines what type of gopher file     */
  162. /*            we've opened.  We'll return the file type tot the    */
  163. /*            caller.                                              */
  164. /*                                                                 */
  165. /*            INPUT:   ident   pointer to first line of file       */
  166. /*                                                                 */
  167. /*            OUTPUT:   MENU   file type is a menu                 */
  168. /*                      FILE   file type is a file                 */
  169. /*                      INDEX  file type is an INDEX (not done)    */
  170. /*******************************************************************/
  171. {
  172. int x;                              /* loop counter */
  173. char buffer[256];
  174.  
  175. /**********/
  176. /*   first, convert the string to upper case...   */
  177. /*********/
  178. strcpy(buffer,ident);
  179. cleantoken(buffer);
  180.  
  181. /**********/
  182. /*   return the type of file.                     */
  183. /*********/
  184.  
  185. if(strcmp(buffer,MENUIDENT)==0) return(MENU);
  186. if(strcmp(buffer,INDEXIDENT)==0) return(INDEX);
  187.  
  188. /**********/
  189. /*   don't know, so assume it's a "file" file...    */
  190. /*********/
  191.  
  192. return(GFILE);
  193. }
  194. /*=================================================================*/
  195. /*=================================================================*/
  196. int menukeywd(char *buffer,char *token,char *operand)
  197. /*******************************************************************/
  198. /*            This routine figures out what type of parm line      */
  199. /*            the current line is.  We'll return the token         */
  200. /*            type to the caller.                                  */
  201. /*                                                                 */
  202. /*            INPUT:   buffer  pointer to first line of file       */
  203. /*                       (Note: string must be null terminated!    */
  204. /*            OUTPUT:   Type of token.  (See in include file...)   */
  205. /*******************************************************************/
  206. {
  207. int x;                              /* loop counter */
  208. char *tokval;
  209. char *oprval;
  210. char tokstr[256];
  211. strcpy(tokstr,buffer);
  212. tokval=strtok(tokstr,"=");
  213. oprval=strtok(NULL,"");
  214. strcpy(token,tokval);
  215. strcpy(operand,oprval);
  216. cleantoken(token);
  217. /*********/
  218. /*  now look at the tokens to see if we have a weener... */
  219. /*********/
  220. if(strcmp(token,TOKTYPE)==0) return(TYPETOK);
  221. if(strcmp(token,TOKDISPLAY)==0) return(DISPLAYTOK);
  222. if(strcmp(token,TOKSELECT)==0) return(SELECTTOK);
  223. if(strcmp(token,TOKHOST)==0) return(HOSTTOK);
  224. if(strcmp(token,TOKPORT)==0) return(PORTTOK);
  225. if(strcmp(token,TOKEND)==0) return(ENDTOK);
  226. return(COMMENTTOK);
  227. }
  228. /*=================================================================*/
  229. /*=================================================================*/
  230. int readaline(char *buffer,FILE *readfile,int maxlen)
  231. /*******************************************************************/
  232. /*       This routine reads a line from the specified file.        */
  233. /*       if a read error occurs, an error message is printed and   */
  234. /*       FALSE is returned.                                        */
  235. /*                                                                 */
  236. /*       INPUT   buffer      pointer to buffer to place line       */
  237. /*               readfile    file structure to read from           */
  238. /*                                                                 */
  239. /*       OUTPUT  buffer      line that was read from the file      */
  240. /*               TRUE        read worked ok                        */
  241. /*               FALSE       read failed!                          */
  242. /*******************************************************************/
  243. {
  244. memset(buffer,0,maxlen);
  245. fread(buffer,maxlen,1,readfile);
  246. if(ferror(readfile))
  247.     {
  248.     perror("FREAD");
  249.     return(FALSE);
  250.     }
  251. return(TRUE);
  252. }
  253. /*=================================================================*/
  254. /*=================================================================*/
  255. void sendafile(char *buffer,FILE *readfile,int maxlen,int sockfd)
  256. /*******************************************************************/
  257. /*   This routine sends a file to the calling client.              */
  258. /*   It assumes the file is a text formatted file.                 */
  259. /*   INPUT:   buffer    pointer to the already read line...        */
  260. /*            readfile  file we're going to read from..            */
  261. /*            maxlen    size of the buffer.                        */
  262. /*            sockfd    socket descriptor for client.              */
  263. /*                                                                 */
  264. /*   OUTPUT:   send the file to the client                         */
  265. /*******************************************************************/
  266. {
  267. int x;
  268. char *moveit;
  269. char outbuf[256];
  270.  
  271. /*******/
  272. /*   send the first line (cause we already read it) */
  273. /*******/
  274.  
  275. cleanafileline(buffer);
  276. sprintf(outbuf,"%s\r\n",buffer);
  277. ebdtoasc(outbuf,strlen(outbuf));
  278. if(write(sockfd,outbuf,strlen(outbuf)) < 0)
  279.      {
  280.      tcperror("SEND");
  281.      return;
  282.      }
  283.  
  284. /*******/
  285. /*   get the rest of the lines of the file and send them... */
  286. /*******/
  287.  
  288. while(1==1)
  289.     {
  290.     readaline(buffer,readfile,maxlen);
  291.     if(feof(readfile)) break;
  292.     if(*buffer=='.')
  293.         {
  294.         moveit = buffer+1;
  295.         memmove(moveit,buffer,strlen(buffer));
  296.         *buffer='.';
  297.         }
  298.     cleanafileline(buffer);
  299.     sprintf(outbuf,"%s\r\n",buffer);
  300.     ebdtoasc(outbuf,strlen(outbuf));
  301.     if(write(sockfd,outbuf,strlen(outbuf)) < 0)
  302.         {
  303.         tcperror("SEND");
  304.         return;
  305.         }
  306.     }
  307. }
  308. /*=================================================================*/
  309. /*=================================================================*/
  310. void sendamenu(char *buffer,FILE *readfile,int maxlen,int sockfd)
  311. /*******************************************************************/
  312. /*   This routine formats a menu file into gopher data & sends it  */
  313. /*   to the client.                                                */
  314. /*   INPUT:   buffer    pointer to the already read line...        */
  315. /*            readfile  file we're going to read from..            */
  316. /*            maxlen    size of the buffer.                        */
  317. /*            sockfd    socket descriptor for client               */
  318. /*                                                                 */
  319. /*   OUTPUT:   send the menu to the client                         */
  320. /*******************************************************************/
  321. {
  322. char *moveit;
  323. char token[133];
  324. char operand[133];
  325. char *typeoftype;             /*pointer for strtok   */
  326. char outbuf[256];
  327. int kindotoken;
  328. int x;                         /* loop counter */
  329. struct menuitem menu;
  330.  
  331. memset(&menu,0,sizeof menu );
  332. while(1==1)
  333.     {
  334.     readaline(buffer,readfile,maxlen);
  335.     if(feof(readfile))
  336.         {
  337.         break;
  338.         }
  339.     if(strlen(buffer)>0) kindotoken = menukeywd(buffer,token,operand);
  340.     switch(kindotoken)
  341.         {
  342.         case TYPETOK:
  343.         cleantoken(operand);
  344.         typeoftype=strtok(operand," ");
  345.         if(strcmp(typeoftype,TYPEFILE)==0) menu.type=GFILE;
  346.         if(strcmp(typeoftype,TYPEMENU)==0) menu.type=MENU;
  347.         if(strcmp(typeoftype,TYPEINDEX)==0) menu.type=INDEX;
  348.         if(strcmp(typeoftype,TYPETELNET)==0) menu.type=TELNET;
  349.         break;
  350.         case DISPLAYTOK:
  351.         strcpy(menu.desc,operand);
  352.         break;
  353.         case SELECTTOK:
  354.         strcpy(menu.select,operand);
  355.         break;
  356.         case HOSTTOK:
  357.         strcpy(menu.hostname,operand);
  358.         break;
  359.         case PORTTOK:
  360.         menu.port=atoi(operand);
  361.         break;
  362.         case ENDTOK:
  363.         if(menu.type==TELNET && menu.port==0) menu.port=0;
  364.         else if(menu.port==0) menu.port=70;
  365.         if(strlen(menu.desc)!=0 && strlen(menu.hostname)!=0)
  366.         sprintf(outbuf,"%d%s\t%s\t%s\t%d\r\n\0",menu.type,menu.desc,
  367.         menu.select,menu.hostname,menu.port);
  368.         fflush(stdout);
  369.         ebdtoasc(outbuf,strlen(outbuf));
  370.         if(write(sockfd,outbuf,strlen(outbuf)) < 0)
  371.             {
  372.             tcperror("SEND");
  373.             return;
  374.             }
  375.         memset(&menu,0,sizeof menu );
  376.         break;
  377.         };
  378.     }
  379. }
  380. /*=================================================================*/
  381. /*=================================================================*/
  382. int process(char *filename,int sockfd)
  383. /*******************************************************************/
  384. /*   This routine Processes the file the user requested.           */
  385. /*   If it's a menu, we'll form a menu line, if it's a             */
  386. /*   file, we'll just send it as is.                               */
  387. /*                                                                 */
  388. /*   INPUT:   filename  pointer to the file name to open           */
  389. /*            sockfd    socket descriptor for the client           */
  390. /*                                                                 */
  391. /*   OUTPUT:   print "gopher" lines.                               */
  392. /*             TRUE  - file printed ok.                            */
  393. /*             FALSE - Error reading or writing                    */
  394. /*******************************************************************/
  395. {
  396. int x;                             /* loop counter*/
  397. char buffer[256];                  /* buffer for input/output*/
  398. FILE *readfile;                    /* declare the file... */
  399. int  numread;                      /* number of items read... */
  400. int  filetype;                     /* type of file we're dealing with*/
  401. char *ptr;                         /* pointer into receive buffer */
  402.  
  403. /************/
  404. /*  First, strip off any "bad" characters and open the file.  */
  405. /************/
  406.  
  407. cleanastring(filename);
  408. if(strlen(filename)==0) strcpy(filename,DEFAULT_DIRECTORY);
  409.     printf("entry requested:%s;",filename);
  410.  
  411. sprintf(buffer,"'%s'",filename); /* make sure userid isn't added */
  412. if((readfile=fopen(buffer,"rb,type=record")) == NULL)
  413.     {
  414.     perror("PROCESS");
  415.     printf("INVALID! requested:%s\n",filename);
  416.     fflush(stdout);
  417.     fflush(stderr);
  418.     return(FALSE);
  419.     }
  420.  
  421. /************/
  422. /*  get the first line and see what type of file we've got.      */
  423. /************/
  424.  
  425. memset(buffer,0,sizeof(buffer));
  426. if(readaline(buffer,readfile,sizeof(buffer))==FALSE) return(FALSE);
  427. filetype=getftype(buffer);
  428.  
  429. /************/
  430. /*  Now let's go do whatever we need to for this file type.      */
  431. /************/
  432.  
  433. switch(filetype)
  434.     {
  435.     case MENU:
  436.     sendamenu(buffer,readfile,sizeof(buffer),sockfd);
  437.     break;
  438.     case GFILE:
  439.     sendafile(buffer,readfile,sizeof(buffer),sockfd);
  440.     break;
  441.     }
  442. if(fclose(readfile) < 0) perror("PROCESS CLOSE");
  443. }
  444. /*=================================================================*/
  445. /*=================================================================*/
  446. void lookatsocket(int sockfd)
  447. /*******************************************************************/
  448. /*                                                                 */
  449. /*    this is a debugging routine;  it looks at the status of a    */
  450. /*    socket.                                                      */
  451. /*******************************************************************/
  452. {
  453. int rc;                        /* return code */
  454. struct linger l;              /* linger structure */
  455. int length;                   /* length variable */
  456. int option;
  457. length = sizeof(l);
  458. if(getsockopt(sockfd,SOL_SOCKET, SO_LINGER,&l,&length)==0)
  459.     {
  460.     printf("l_onoff=%d\n",l.l_onoff);
  461.     printf("l_linger=%d\n",l.l_linger);
  462.     }
  463. else tcperror("GETSOCKOPT");
  464.  
  465. length = sizeof(option);
  466. if(getsockopt(sockfd,SOL_SOCKET, SO_ERROR,&option,&length)==0)
  467.     {
  468.     printf("so_error=%d\n",option);
  469.     }
  470. else tcperror("GETSOCKOPT");
  471. if(fcntl(sockfd,F_SETFL,FNDELAY)!=0) tcperror("FCNTL");
  472.  
  473. while(1==1)
  474.     {
  475.     char buffer[256]; int len;
  476.     len=recv(sockfd,buffer,sizeof(buffer)-1,0);
  477.     if((len==-1)&&(errno==EWOULDBLOCK))
  478.         {
  479.         break;
  480.         }
  481.     else if(len==-1)
  482.         {
  483.         tcperror("recv");
  484.         break;
  485.         }
  486.     else 
  487.         {
  488.         int x;
  489.         buffer[255] = 0;
  490.         printf("buffer =%s\n",buffer);
  491.         for(x=0;x<len;x++) printf("%x ",buffer[x]);
  492.         printf("\n");
  493.         break;
  494.         }
  495.     }
  496. }
  497.